// Mesh Format Loader B3D
// (c) jimon game studio

#include "CMeshFormatLoader_B3D.h"

#ifdef JE_SUPPORT_FILEFORMAT_B3D

#include "ILogManager.h"
#include "IVariables.h"

//#define JE_DEBUG_B3D

namespace je
{
	namespace scene
	{
		//! Constructor
		CMeshFormatLoader_B3D::CMeshFormatLoader_B3D()
		{
		}

		//! Destructor
		CMeshFormatLoader_B3D::~CMeshFormatLoader_B3D()
		{
		}

		//! Load Mesh
		jeMesh * CMeshFormatLoader_B3D::LoadMesh(core::IBuffer * DataBuffer,video::IRender * Render)
		{
			#ifdef JE_DEBUG_B3D
			JELOG("Enesea B3D Loader")
			#endif

			DataBuffer->Lock(core::BLT_READ);
			DataBuffer->SetPosition(0);
			DataBuffer->SetStreamWorkMode(true);

			#ifdef JE_DEBUG_B3D
			JELOG("Stage 1")
			#endif

			B3DFile * File = ReadFile(DataBuffer,Render);
			DataBuffer->UnLock();

			#ifdef JE_DEBUG_B3D
			JELOG("Stage 2")
			#endif
			jeMesh * Mesh = LoadMeshNode(File->Node,File,Render);

			#ifdef JE_DEBUG_B3D
			JELOG("Finish")
			#endif

			JEDELETE(File)
			return Mesh;
		}

		//! Save Mesh
		void CMeshFormatLoader_B3D::SaveMesh(core::IBuffer * DataBuffer,jeMesh * Mesh)
		{
			// TODO
			JELOG_E("No Support")
		}

		//! Return true if mesh loader can work with this data
		u1 CMeshFormatLoader_B3D::CanWorkWithThis(core::IBuffer * DataBuffer)
		{
			DataBuffer->Lock(core::BLT_READ);
			DataBuffer->SetPosition(0);
			DataBuffer->SetStreamWorkMode(true);
			B3DHeader * Header = ReadHeader(DataBuffer);
			DataBuffer->UnLock();

			u1 CanWorkWithThis = (memcmp(Header->Name,"BB3D",4) ? false : true);
			JEDELETE(Header)

			return CanWorkWithThis;
		}

		CMeshFormatLoader_B3D::B3DHeader * CMeshFormatLoader_B3D::ReadHeader(core::IBuffer * DataBuffer)
		{
			B3DHeader * Header = NULL;
			JENEW(Header,B3DHeader)
			DataBuffer->Read(Header,8);
			return Header;
		}

		CMeshFormatLoader_B3D::B3DTexture * CMeshFormatLoader_B3D::ReadTexture(core::IBuffer * DataBuffer)
		{
			B3DTexture * Texture = NULL;
			JENEW(Texture,B3DTexture)

			c8 Buff;
			DataBuffer->Read(&Buff,1);
			while(Buff != '\0')
			{
				Texture->FileName += Buff;
				DataBuffer->Read(&Buff,1);
			}

			DataBuffer->Read(&Texture->Flags,4);
			DataBuffer->Read(&Texture->Blend,4);
			DataBuffer->Read(&Texture->Pos,8);
			DataBuffer->Read(&Texture->Scale,8);
			DataBuffer->Read(&Texture->Rotation,4);

			#ifdef JE_DEBUG_B3D
			jeStringc Log = "Texture:File='";
			Log+=Texture->FileName;
			Log+="',Flags=";
			Log+=Texture->Flags;
			Log+=",Blend=";
			Log+=Texture->Blend;
			JELOG(Log)
			#endif

			return Texture;
		}

		CMeshFormatLoader_B3D::B3DBrush * CMeshFormatLoader_B3D::ReadBrush(core::IBuffer * DataBuffer,s32 NumOfTextures)
		{
			B3DBrush * Brush = NULL;
			JENEW(Brush,B3DBrush)

			c8 Buff;
			DataBuffer->Read(&Buff,1);
			while(Buff != '\0')
			{
				Brush->Name += Buff;
				DataBuffer->Read(&Buff,1);
			}

			DataBuffer->Read(&Brush->Color,16);
			DataBuffer->Read(&Brush->Shininess,4);
			DataBuffer->Read(&Brush->Blend,4);
			DataBuffer->Read(&Brush->Fx,4);

			Brush->NumOfTextures = NumOfTextures;

			JENEW_A(Brush->TextureIds,s32,NumOfTextures)
			for(s32 i = 0;i < NumOfTextures;i++)
			{
				s32 TextureId = 0;
				DataBuffer->Read(&TextureId,4);
				Brush->TextureIds[i] = TextureId;
			}

			#ifdef JE_DEBUG_B3D
			jeStringc Log = "Brush:Name='";
			Log+=Brush->Name;
			Log+="',Blend=";
			Log+=Brush->Blend;
			Log+=",Fx=";
			Log+=Brush->Fx;

			Log+=",Texs=";
			Log+=Brush->TextureIds[0];
			for(s32 i = 1;i < NumOfTextures;i++)
				Log+=jeStringc(",")+jeStringc(Brush->TextureIds[i]);
			JELOG(Log)
			#endif

			return Brush;
		}

		CMeshFormatLoader_B3D::B3DSurface * CMeshFormatLoader_B3D::ReadSurface(core::IBuffer * DataBuffer,s32 SurfaceDistPos,video::IRender * Render)
		{
			B3DSurface * Surface = NULL;
			JENEW(Surface,B3DSurface)

			DataBuffer->Read(&Surface->Flags,4);
			DataBuffer->Read(&Surface->TexCoordsSets,4);
			DataBuffer->Read(&Surface->TexCoordSetSize,4);

			s32 DataBlockSize = SurfaceDistPos - DataBuffer->GetPosition();

			Surface->VB = Render->CreateHardwareBuffer(video::G3DT_VERTEX);
			Surface->VB->Lock(core::BLT_WRITE);
			Surface->VB->Allocate(DataBlockSize);
			Surface->VB->WriteFrom(DataBuffer,DataBlockSize);
			Surface->VB->UnLock();

			#ifdef JE_DEBUG_B3D
			jeStringc Log = "Surface:Flags=";
			Log+=Surface->Flags;
			Log+=",TexCoordsSets=";
			Log+=Surface->TexCoordsSets;
			Log+=",TexCoordSetSize=";
			Log+=Surface->TexCoordSetSize;
			Log+=",DataBlockSize=";
			Log+=DataBlockSize;
			JELOG(Log)
			#endif

			return Surface;
		}

		CMeshFormatLoader_B3D::B3DSurfaceIndexes * CMeshFormatLoader_B3D::ReadSurfaceIndexes(core::IBuffer * DataBuffer,B3DSurface * Surface,s32 SurfaceIndexesDistPos,video::IRender * Render)
		{
			B3DSurfaceIndexes * SurfaceIndexes = NULL;
			JENEW(SurfaceIndexes,B3DSurfaceIndexes)

			DataBuffer->Read(&SurfaceIndexes->BrushId,4);

			SurfaceIndexes->Array = Render->CreateHardwareBufferArray();

			s32 Stride = 12+Surface->TexCoordsSets*Surface->TexCoordSetSize*4;
			if(Surface->Flags & 1)
				Stride += 12;
			if(Surface->Flags & 2)
				Stride += 16;

			SurfaceIndexes->Array->AttachBuffer(Surface->VB,video::HBAL_POSITION,3,4,Stride,0);
			s32 Offset = 12;
			if(Surface->Flags & 1)
			{
				SurfaceIndexes->Array->AttachBuffer(Surface->VB,video::HBAL_NORMAL,3,4,Stride,Offset);
				Offset+=12;
			}
			if(Surface->Flags & 2)
			{
				SurfaceIndexes->Array->AttachBuffer(Surface->VB,video::HBAL_COLOR,4,4,Stride,Offset);
				Offset+=16;
			}
			SurfaceIndexes->Array->AttachBuffer(Surface->VB,video::HBAL_UV,2,4,Stride,Offset);

			s32 VertexCount = Surface->VB->GetSize() / Stride;
			s32 DataBlockSize = SurfaceIndexesDistPos - DataBuffer->GetPosition();
			s32 IndexSize;

			video::IHardwareBuffer * IB = Render->CreateHardwareBuffer(video::G3DT_INDEX);
			IB->Lock(core::BLT_WRITE);

			if(VertexCount > 65535)
			{
				IndexSize = 4;
				IB->Allocate(DataBlockSize);
				IB->WriteFrom(DataBuffer,DataBlockSize);
			}
			else
			{
				s32 Koef = (VertexCount>255)?2:4;
				IndexSize = 4/Koef;
				u8 * Temp = NULL;
				JENEW_A(Temp,u8,DataBlockSize/Koef)
				u8 * Temp2 = NULL;
				JENEW_A(Temp2,u8,DataBlockSize)
				DataBuffer->Read(Temp2,DataBlockSize);
				core::RemapArray(Temp2,4,DataBlockSize/4,Temp,IndexSize);
				JEDELETE_A(Temp2)
				IB->Allocate(DataBlockSize/Koef);
				IB->Write(Temp,DataBlockSize/Koef);
				JEDELETE_A(Temp)
			}

			IB->UnLock();

			SurfaceIndexes->Array->AttachBuffer(IB,video::HBAL_INDEXES,1,IndexSize);
			IB->Drop();

			return SurfaceIndexes;
		}

		void CMeshFormatLoader_B3D::ReadKey(B3DKey * Key,core::IBuffer * DataBuffer,s32 Flags,u1 ReadFrame)
		{
			if(ReadFrame)
				DataBuffer->Read(&Key->Frame,4);

			if(Flags & 1)
				DataBuffer->Read(&Key->Position,12);

			if(Flags & 2)
				DataBuffer->Read(&Key->Scale,12);

			if(Flags & 4)
			{
				DataBuffer->Read(&Key->Rotation,16);
				CorrentQuaternion(Key->Rotation);
			}
		}

		CMeshFormatLoader_B3D::B3DBone * CMeshFormatLoader_B3D::ReadBone(core::IBuffer * DataBuffer)
		{
			B3DBone * Bone = NULL;
			JENEW(Bone,B3DBone)
			DataBuffer->Read(&Bone->VertexId,4);
			DataBuffer->Read(&Bone->Weight,4);
			return Bone;
		}

		CMeshFormatLoader_B3D::B3DAnimation * CMeshFormatLoader_B3D::ReadAnimation(core::IBuffer * DataBuffer)
		{
			B3DAnimation * Animation = NULL;
			JENEW(Animation,B3DAnimation)
			DataBuffer->Read(&Animation->Flags,4);
			DataBuffer->Read(&Animation->Frames,4);
			DataBuffer->Read(&Animation->Fps,4);
			return Animation;
		}

		CMeshFormatLoader_B3D::B3DNode * CMeshFormatLoader_B3D::ReadNode(core::IBuffer * DataBuffer,s32 NodeDistPos,video::IRender * Render,s32 lvl)
		{
			B3DNode * Node = NULL;
			JENEW(Node,B3DNode)

			c8 Buff;
			DataBuffer->Read(&Buff,1);
			while(Buff != '\0')
			{
				Node->Name += Buff;
				DataBuffer->Read(&Buff,1);
			}

			#ifdef JE_DEBUG_B3D
			JELOG(jeStringc("Node Name : ")+Node->Name)
			#endif

			DataBuffer->Read(&Node->Position,12);
			DataBuffer->Read(&Node->Scale,12);
			DataBuffer->Read(&Node->Rotation,16);
			CorrentQuaternion(Node->Rotation);

			while(DataBuffer->GetPosition() != (u32)NodeDistPos)
			{
				B3DHeader * Header = ReadHeader(DataBuffer);

				if(!memcmp(Header->Name,"MESH",4))
				{
					JENEW(Node->Mesh,B3DMesh)
					DataBuffer->Read(&Node->Mesh->BrushId,4);
				}
				else if(!memcmp(Header->Name,"VRTS",4))
				{
					s32 DistPos = Header->Length + DataBuffer->GetPosition();

					if(Node->Mesh->Surface)
					{
						JELOG_E("Multiply VRTS in B3D, ignore")
						JEDELETE(Node->Mesh->Surface)
					}

					Node->Mesh->Surface = ReadSurface(DataBuffer,DistPos,Render);
				}
				else if(!memcmp(Header->Name,"TRIS",4))
				{
					s32 DistPos = Header->Length + DataBuffer->GetPosition();
					Node->Mesh->SurfacesIndexes.InsertElement(ReadSurfaceIndexes(DataBuffer,Node->Mesh->Surface,DistPos,Render));
				}
				else if(!memcmp(Header->Name,"BONE",4))
				{
					s32 DistPos = Header->Length + DataBuffer->GetPosition();
					while(DistPos != DataBuffer->GetPosition()) // make it faster
						Node->Bones.InsertElement(ReadBone(DataBuffer));
				}
				else if(!memcmp(Header->Name,"KEYS",4))
				{
					s32 DistPos = Header->Length + DataBuffer->GetPosition();
					s32 Flags = 0;
					DataBuffer->Read(&Flags,4);
					if(Node->Keys.GetSize() == 0) // make it faster
					{
						while(DistPos != DataBuffer->GetPosition())
						{
							B3DKey * Key = NULL;
							JENEW(Key,B3DKey)
							ReadKey(Key,DataBuffer,Flags);
							Node->Keys.InsertElement(Key);
						}
					}
					else
					{
						while(DistPos != DataBuffer->GetPosition())
						{
							s32 Frame = 0;
							DataBuffer->Read(&Frame,4);
							u1 WriteOk = false;
							for(u32 i = 0; i < Node->Keys.GetSize();i++)
							{
								if(Frame == Node->Keys[i]->Frame)
								{
									WriteOk = true;
									ReadKey(Node->Keys[i],DataBuffer,Flags,false);
									break;
								}
							}
							if(!WriteOk)
							{
								B3DKey * Key = NULL;
								JENEW(Key,B3DKey)
								Key->Frame = Frame;
								ReadKey(Key,DataBuffer,Flags,false);
								Node->Keys.InsertElement(Key);
							}

						}
					}
				}
				else if(!memcmp(Header->Name,"ANIM",4))
				{
					if(Node->Animation)
					{
						JELOG_E("Multiply ANIM in B3D, ignore")
						JEDELETE(Node->Animation)
					}
					Node->Animation = ReadAnimation(DataBuffer);
				}
				else if(!memcmp(Header->Name,"NODE",4))
				{
					Node->Nodes.InsertElement(ReadNode(DataBuffer,Header->Length+DataBuffer->GetPosition(),Render,lvl+1));
				}
				else
				{
					JELOG_W(jeStringc("Unknown b3d header : ")+Header->Name+jeStringc(", ignore"))
					DataBuffer->SetPosition(Header->Length,true);
				}
				JEDELETE(Header)
			}

			return Node;
		}

		CMeshFormatLoader_B3D::B3DFile * CMeshFormatLoader_B3D::ReadFile(core::IBuffer * DataBuffer,video::IRender * Render)
		{
			B3DFile * File = NULL;
			JENEW(File,B3DFile)

			File->Header = ReadHeader(DataBuffer);
			DataBuffer->Read(&File->Version,4);

			while(DataBuffer->GetPosition() < (DataBuffer->GetSize()-1))
			{
				B3DHeader * Header = ReadHeader(DataBuffer);

				if(!memcmp(Header->Name,"TEXS",4))
				{
					s32 DistPos = Header->Length + DataBuffer->GetPosition();
					while((u32)DistPos != DataBuffer->GetPosition())
						File->Textures.InsertElement(ReadTexture(DataBuffer));
				}
				else if(!memcmp(Header->Name,"BRUS",4))
				{
					s32 DistPos = Header->Length + DataBuffer->GetPosition();
					s32 NumOfTextures = 0;
					DataBuffer->Read(&NumOfTextures,4);
					while((u32)DistPos != DataBuffer->GetPosition())
						File->Brushes.InsertElement(ReadBrush(DataBuffer,NumOfTextures));
				}
				else if(!memcmp(Header->Name,"NODE",4))
					File->Node = ReadNode(DataBuffer,Header->Length+DataBuffer->GetPosition(),Render);

				JEDELETE(Header)
			}

			return File;
		}

		u8 SortBonesMapping(jeSkeletonBone * Bone1,jeSkeletonBone * Bone2)
		{
			if(Bone1->GetBoneId() > Bone2->GetBoneId())
				return 1;
			if(Bone1->GetBoneId() < Bone2->GetBoneId())
				return 2;
			return 4;
		}

		jeMesh * CMeshFormatLoader_B3D::LoadMeshNode(B3DNode * Node,B3DFile * File,video::IRender * Render)
		{
			jeMesh * Mesh = NULL;
			JENEW(Mesh,jeMesh)

			if(Node->Mesh)
			{
				for(u32 SurfIndex = 0;SurfIndex<Node->Mesh->SurfacesIndexes.GetSize();SurfIndex++)
				{
					video::jeRenderOperation_Draw * Op = NULL;
					JENEW(Op,video::jeRenderOperation_Draw)
					Op->SetArray(Node->Mesh->SurfacesIndexes[SurfIndex]->Array);

					ISurface * Surface = CreateSurface(Render,video::ROT_DRAW_TRIANGLES,Op);
					Op->Drop();

					s32 CurrentBrushId = Node->Mesh->SurfacesIndexes[SurfIndex]->BrushId;

					if(CurrentBrushId == -1)
						CurrentBrushId = Node->Mesh->BrushId;

					#ifdef JE_DEBUG_B3D
					JELOG(jeStringc("Material Num : ")+jeStringc(CurrentBrushId))
					#endif

					u1 UseUniqueMaterial = core::GetVariables()->GetVariablec8("SceneManager_SufracesDefaultUseUniqueMaterial")?true:false;
					u1 UseUniqueTexture = core::GetVariables()->GetVariablec8("SceneManager_SufracesDefaultUseUniqueTexture")?true:false;
					u1 UseUniqueShader = core::GetVariables()->GetVariablec8("SceneManager_SufracesDefaultUseUniqueShader")?true:false;

					if((CurrentBrushId != -1) && (File->Brushes[CurrentBrushId]->TextureIds[0] != -1))
						Surface->SetMaterialResource(JE_MATERIALRESOURCE(File->Textures[File->Brushes[CurrentBrushId]->TextureIds[0]]->FileName),UseUniqueMaterial,UseUniqueTexture,UseUniqueShader);

					if((!Surface->GetMaterialResource()) && core::GetVariables()->GetVariablec8("SceneManager_EnableSufracesDefaultMaterial"))
						Surface->SetMaterialResource(JE_MATERIALRESOURCE(core::GetVariables()->GetVariableString("SceneManager_SufracesDefaultMaterialName").c_str()),UseUniqueMaterial,UseUniqueTexture,UseUniqueShader);

					Mesh->AddSurface(Surface);
					Surface->Drop();

					jeMatrix4f ModelMatrix;
					ModelMatrix.Scale(Node->Scale);
					ModelMatrix = Node->Rotation.GetMatrix() * ModelMatrix;
					ModelMatrix.Translate(Node->Position);

					Mesh->SetModelMatrix(ModelMatrix);
				}
			}

			Mesh->SetName(Node->Name.c_str());

			jeSkeletonBone * RootBone = NULL;

			for(u32 i = 0;i<Node->Nodes.GetSize();i++)
			{
				if(Node->Nodes[i]->Mesh)
				{
					jeMesh * ChildrenMesh = LoadMeshNode(Node->Nodes[i],File,Render);
					Mesh->AddChildren(ChildrenMesh);
					ChildrenMesh->Drop();
				}

				if(Node->Nodes[i]->Bones.GetSize() || Node->Nodes[i]->Keys.GetSize())
				{
					video::IHardwareBufferArray * BaseSurfaceArray = static_cast<video::jeRenderOperation_Draw*>((*Mesh->GetSurfaces().begin())->GetRenderOperation())->Array;
					u32 VertexCount = BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Buffer->GetSize() / BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Stride;
					u32 BonesDataSize = (sizeof(u8)*4+sizeof(f32)*4)*VertexCount;

					u8 * BonesData = NULL;
					JENEW_A(BonesData,u8,BonesDataSize)
					memset(BonesData,0,BonesDataSize);

					u32 BoneId = 1;
					jeSkeletonBone * Bone = LoadBones(Node->Nodes[i],BonesData,BoneId);

					video::IHardwareBuffer * BaseSurfaceBuffer = BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Buffer;

					core::jeMemoryBuffer * TempBuffer = NULL;
					JENEW(TempBuffer,core::jeMemoryBuffer)

					TempBuffer->Lock(core::BLT_READWRITE);
					BaseSurfaceBuffer->Lock(core::BLT_READWRITE);

					TempBuffer->Allocate(BaseSurfaceBuffer->GetSize());
					TempBuffer->WriteFrom(BaseSurfaceBuffer,BaseSurfaceBuffer->GetSize());

					BaseSurfaceBuffer->DeAllocate();

					BaseSurfaceBuffer->Allocate(TempBuffer->GetSize()+BonesDataSize);
					BaseSurfaceBuffer->WriteFrom(TempBuffer,TempBuffer->GetSize());

					TempBuffer->DeAllocate();
					TempBuffer->UnLock();
					JEDELETE_A(TempBuffer)

					BaseSurfaceBuffer->Merge(BonesData,BonesDataSize,20,BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Stride + 20);

					JEDELETE_A(BonesData)

					BaseSurfaceBuffer->UnLock();

					for(u32 i=0;i<JE_MAX_SHADER_VERTEX_LAYERS;i++)
						if(BaseSurfaceArray->GetLayerInfo((video::HardwareBufferArrayLayers)i).Buffer == BaseSurfaceBuffer)
							BaseSurfaceArray->GetLayerInfo((video::HardwareBufferArrayLayers)i).Stride+=20;

					BaseSurfaceArray->AttachBuffer(BaseSurfaceBuffer,video::HBAL_BONES_IDS,4,1,BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Stride,BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Stride-20,true);
					BaseSurfaceArray->AttachBuffer(BaseSurfaceBuffer,video::HBAL_BONES_W,4,4,BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Stride,BaseSurfaceArray->GetLayerInfo(video::HBAL_POSITION).Stride-16);

					if(!RootBone)
						RootBone = Bone;
					else
						JELOG_E("Multiply roots in skin !")
				}
			}

			if(RootBone)
			{
				RootBone->CalculateBindPoseGlobalMatrixes();

				jeSkeleton * Skeleton = NULL;
				JENEW(Skeleton,jeSkeleton(RootBone))

				if(Node->Animation)
				{
					jeSkeletonAnimation * anim = NULL;
					JENEW(anim,jeSkeletonAnimation(0,Node->Animation->Frames-1,Node->Animation->Fps))
					Skeleton->GetAnimations().InsertElement(anim);
				}

				MapBonesToSkeleton(RootBone,Skeleton);

				Skeleton->GetBonesMapping().QuickSort((jeSkeleton::BonesMappingIdType::jeSortCompareFunction)&SortBonesMapping);

				Mesh->SetSkeleton(Skeleton);
				Skeleton->Drop();
			}

			return Mesh;
		}

		jeSkeletonBone * CMeshFormatLoader_B3D::LoadBones(B3DNode * Node,void * BonesData,u32 & BoneId)
		{
			jeMatrix4f BoneMatrix;
			BoneMatrix.Scale(Node->Scale);
			BoneMatrix = Node->Rotation.GetMatrix() * BoneMatrix;
			BoneMatrix.Translate(Node->Position);

			jeSkeletonBone * Bone = NULL;
			JENEW(Bone,jeSkeletonBone(BoneMatrix))

			Bone->SetBoneId(BoneId++);

			for(u32 i = 0; i < Node->Keys.GetSize(); i++)
			{
				jeSkeletonBone::jeAnimationKey * Key = NULL;
				JENEW(Key,jeSkeletonBone::jeAnimationKey)
				Key->Frame = Node->Keys[i]->Frame;
				Key->Position = Node->Keys[i]->Position;
				Key->Scale = Node->Keys[i]->Scale;
				Key->Orientation = Node->Keys[i]->Rotation;
				Bone->GetKeys().InsertElement(Key);
			}
			
			for(u32 i = 0; i < Node->Bones.GetSize(); i++)
			{
				u8 * BasePtr = (u8*)BonesData+20*Node->Bones[i]->VertexId;

				u8 k = 0;
				for(u8 k1 = 0 ; k1 < 4 ; k1++)
					if(BasePtr[k1] == 0)
					{
						k = k1;
						break;
					}

				BasePtr[k] = Bone->GetBoneId();
				f32 * BasePtr2 = (f32*)(BasePtr+4);
				BasePtr2[k] = Node->Bones[i]->Weight;
			}

			for(u32 i = 0;i<Node->Nodes.GetSize();i++)
			{
				if(Node->Nodes[i]->Bones.GetSize() || Node->Nodes[i]->Keys.GetSize())
				{
					jeSkeletonBone * ChildBone = LoadBones(Node->Nodes[i],BonesData,BoneId);
					Bone->GetChildrens().InsertElement(ChildBone);
					ChildBone->SetParent(Bone);
				}
			}

			return Bone;
		}

		void CMeshFormatLoader_B3D::MapBonesToSkeleton(jeSkeletonBone * Bone,jeSkeleton * Skeleton)
		{
			Skeleton->GetBonesMapping().InsertElement(Bone);
			for(u32 i=0;i<Bone->GetChildrens().GetSize();i++)
				MapBonesToSkeleton(Bone->GetChildrens()[i],Skeleton);
		}


	}
}

#endif
